/*
 * @Author: tongbin.xtb
 * @Date: 2018-11-28 11:57:47
 * @Last Modified by: tongbin.xtb
 * @Last Modified time: 2018-12-03 21:55:10
 */

/* global mouseEnterEdge, startMove, endMove, mouseLeaveEdge, bpmn */

const { mouseEnterEdge, startMove, mouseLeaveEdge, mouseMoveEdge, endMove } = require('../utils/edgeUtils');
const BPMN = require('../bpmn');

let holdEdge;
let hoverEdge;

BPMN.registerBehaviour('bpmnMoveEdgeController', bpmn => {
  const graph = bpmn.getGraph();
  const rootGroup = graph.getRootGroup();
  let delegation;
  graph.behaviourOn('edge:mouseenter', ev => {
    if (holdEdge || !ev.item) {
      return;
    }
    hoverEdge = ev.item;
    mouseEnterEdge({
      graph,
      bpmn,
      ev,
      backUpCursor: true
    });
  });
  graph.behaviourOn('edge:mousedown', ev => {
    const item = ev.item;
    startMove(graph, ev);
    holdEdge = item;
  });
  graph.behaviourOn('mouseup', () => {
    if (holdEdge) {
      endMove({ graph, item: holdEdge });
      holdEdge = undefined;
    }
  });
  graph.behaviourOn('mousemove', ev => {
    if (holdEdge) {
      // 根据位移来重新计算控制点
      mouseMoveEdge(graph, holdEdge, ev);
    } else if (hoverEdge) {
      mouseEnterEdge({
        graph,
        bpmn,
        ev: { ...ev, item: hoverEdge },
        backUpCursor: false
      });
    }
  });
  graph.behaviourOn('edge:mouseleave', () => {
    if (!holdEdge) {
      if (hoverEdge) {
        mouseLeaveEdge({ graph, bpmn, item: hoverEdge });
        hoverEdge = undefined;
      }
    }
  });
  graph.behaviourOn('node:dragstart', ev => {
    const startBox = ev.item.getBBox();
    delegation = bpmn.getDelegation([ startBox ], rootGroup);
    bpmn.set('bpmnNodePanDelegation', delegation);
    bpmn.set('bpmnNodePanStartBox', startBox);
    bpmn.set('bpmnNodePanStartPoint', {
      x: ev.x,
      y: ev.y
    });
    bpmn.set('bpmnNodePanStartItem', ev.item);
  });
  graph.behaviourOn('node:dragend', ev => {
    // console.log('node:dragend', holdNode, ev);
    const delegation = bpmn.get('bpmnNodePanDelegation');
    const startPoint = bpmn.get('bpmnNodePanStartPoint');
    const holdNode = bpmn.get('bpmnNodePanStartItem');
    if (holdNode) {
      holdNode.getEdges().forEach(edge => {
        graph.update(edge, {
          nodeMoved: {
            item: holdNode.id,
            start: startPoint,
            delta: {
              x: ev.x - startPoint.x,
              y: ev.y - startPoint.y
            }
          }
        });
      });
    }
    delegation.remove();
    resetStatus();
  });
  function resetStatus() {
    bpmn.set('panItemDelegation', undefined);
    bpmn.set('panItemStartBox', undefined);
    bpmn.set('panItemStartPoint', undefined);
    delegation = undefined;
  }
}, [ 'startPanItem', 'processPanItem', 'endPanItem' ]);
